/*
 * 
 *
 *
 */
package com.hboxs.asl.dao.impl;

import com.hboxs.asl.Page;
import com.hboxs.asl.Pageable;
import com.hboxs.asl.dao.LetterDao;
import com.hboxs.asl.entity.Letter;
import com.hboxs.asl.entity.Member;
import org.springframework.stereotype.Repository;

import javax.persistence.FlushModeType;
import javax.persistence.NoResultException;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.List;

/**
 * Dao - 私信
 */
@Repository("letterDaoImpl")
public class LetterDaoImpl extends BaseDaoImpl<Letter, Long> implements LetterDao {

    @Override
    public List<Letter> findLetterPage(Member member) {
        String jpql = "select letters from Letter letters where (letters.forLetter is null and letters.sender = (:sender)) or (letters.forLetter is null and letters.receiver = (:receiver))";
        try {
            return entityManager.createQuery(jpql, Letter.class).setFlushMode(FlushModeType.COMMIT).setParameter("sender", member).setParameter("receiver", member).getResultList();
        } catch (NoResultException e) {
            return null;
        }
    }

    @Override
    public Letter ifHasSend(Member sender, Member receiver) {
        String jpql = "select letters from Letter letters where letters.sender = :sender and letters.receiver = :receiver and " +
                "letters.forLetter is null ";
        try {
            return entityManager.createQuery(jpql, Letter.class).setFlushMode(FlushModeType.COMMIT).setParameter("sender", sender)
                    .setParameter("receiver", receiver).getSingleResult();
        } catch (NoResultException e) {
            return null;
        }
    }

    @Override
    public Page<Letter> findPageLetters(Pageable pageable) {
        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
        CriteriaQuery<Letter> criteriaQuery = criteriaBuilder.createQuery(Letter.class);
        Root<Letter> root = criteriaQuery.from(Letter.class);
        criteriaQuery.select(root);
        Predicate restrictions = criteriaBuilder.conjunction();
        restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.isNull(root.get("forLetter")));
        criteriaQuery.where(restrictions);
        criteriaQuery.orderBy(criteriaBuilder.desc(root.get("createDate")));
        return super.findPage(criteriaQuery, pageable);
    }

    @Override
    public Page<Letter> findPageLetterByTime(Pageable pageable, Letter letter) {
        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
        CriteriaQuery<Letter> criteriaQuery = criteriaBuilder.createQuery(Letter.class);
        Root<Letter> root = criteriaQuery.from(Letter.class);
        criteriaQuery.select(root);
        Predicate restrictions = criteriaBuilder.conjunction();
        restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("forLetter"), letter));
        criteriaQuery.where(restrictions);
        criteriaQuery.orderBy(criteriaBuilder.desc(root.get("createDate")));
        return super.findPage(criteriaQuery, pageable);
    }

    @Override
    public List<Letter> findLetterDetailList(Letter letter) {
        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
        CriteriaQuery<Letter> criteriaQuery = criteriaBuilder.createQuery(Letter.class);
        Root<Letter> root = criteriaQuery.from(Letter.class);
        criteriaQuery.select(root);
        Predicate restrictions = criteriaBuilder.conjunction();
        restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("forLetter"), letter));
        criteriaQuery.where(restrictions);
        criteriaQuery.orderBy(criteriaBuilder.desc(root.get("createDate")));
        return super.findList(criteriaQuery, null,null,null,null);
    }

    @Override
    public long hasNotReadLetters(Member receiver, Long letterId) {
        return 0;
    }
}
